<?php
require_once("config.php"); // 数据库连接配置
session_start();

// 反爬机制配置
$antiSpamConfig = [
    'login_attempts_limit' => 5,       // 登录尝试次数限制
    'block_time' => 15 * 60,           // 封锁时间（秒）
    'check_interval' => 60 * 60,       // 检查时间窗口（秒）
    'ip_blacklist_file' => __DIR__ . '/data/ip_blacklist.txt',
    'login_attempts_file' => __DIR__ . '/data/login_attempts.json'
];


$antiSpamDir = dirname($antiSpamConfig['login_attempts_file']);
if (!file_exists($antiSpamDir)) {
    mkdir($antiSpamDir, 0777, true);
}

// 获取客户端IP地址
function getClientIP() {
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        return $_SERVER['HTTP_CLIENT_IP'];
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
    return $_SERVER['REMOTE_ADDR'];
}

// 检查IP是否在黑名单中
function isIPBlacklisted($ip, $blacklistFile) {
    if (!file_exists($blacklistFile)) return false;
    
    $blacklist = file($blacklistFile, FILE_IGNORE_NEW_LINES);
    return in_array($ip, $blacklist);
}

// 记录登录尝试
function logLoginAttempt($ip, $success, $config) {
    $attempts = [];
    $file = $config['login_attempts_file'];
    
    // 读取现有记录
    if (file_exists($file)) {
        $json = file_get_contents($file);
        $attempts = json_decode($json, true) ?: [];
    }
    
    // 添加新记录
    $attempts[] = [
        'ip' => $ip,
        'time' => time(),
        'success' => $success
    ];
    
    // 只保留指定时间窗口内的记录
    $threshold = time() - $config['check_interval'];
    $attempts = array_filter($attempts, function($a) use ($threshold) {
        return $a['time'] >= $threshold;
    });
    
    // 保存记录
    file_put_contents($file, json_encode(array_values($attempts)));
    
    // 如果失败次数超过限制，将IP加入黑名单
    $ipAttempts = array_filter($attempts, function($a) use ($ip) {
        return $a['ip'] === $ip && !$a['success'];
    });
    
    if (count($ipAttempts) >= $config['login_attempts_limit']) {
        addToIPBlacklist($ip, $config['ip_blacklist_file']);
        return true; // IP已被封锁
    }
    
    return false;
}

// 添加IP到黑名单
function addToIPBlacklist($ip, $blacklistFile) {
    file_put_contents($blacklistFile, $ip . PHP_EOL, FILE_APPEND);
}

// 检查并处理验证码请求
if (isset($_GET['get_captcha'])) {
    // 可以添加IP请求频率检查
    header('Content-Type: image/png');
    include('verify.php');
    exit;
}

// 获取客户端IP
$clientIP = getClientIP();

// 检查IP是否被封锁
if (isIPBlacklisted($clientIP, $antiSpamConfig['ip_blacklist_file'])) {
    http_response_code(403);
    die("您的IP已被封锁，请稍后再试。");
}

// 密码哈希加密配置（可选：设置算法参数）
// define('PASSWORD_COST', 12); // 默认10，数值越大越安全但性能消耗越高

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = trim($_POST["username"]); // 去除首尾空格
    $plainPassword = trim($_POST["pwd"]); // 原始密码（不存储）
    $code = trim($_POST["code"]);

    // 输入验证：非空检查
    if (empty($username) || empty($plainPassword) || empty($code)) {
        logLoginAttempt($clientIP, false, $antiSpamConfig);
        echo "<script>alert('用户名、密码或验证码不可为空！'); location.href='login.php';</script>";
        exit();
    }

    // 验证码验证（区分大小写需调整strtolower）
    if (strtolower($_SESSION["code"]) !== strtolower($code)) {
        logLoginAttempt($clientIP, false, $antiSpamConfig);
        echo "<script>alert('验证码错误!请重新登录！'); location.href='login.php';</script>";
        exit();
    }

    // 数据库查询：获取用户哈希密码
    $stmt = $connect->prepare("SELECT id, username, password FROM librarian WHERE username=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($user = $result->fetch_assoc()) {
        // 验证密码哈希
        if (password_verify($plainPassword, $user["password"])) {
            // 密码正确，更新会话并跳转
            logLoginAttempt($clientIP, true, $antiSpamConfig);
            
            $_SESSION["user_id"] = $user["id"];
            $_SESSION["username"] = $user["username"];
            $_SESSION["login_time"] = time(); // 记录登录时间（可选）
            
            // 自动更新哈希版本（可选：若使用旧算法）
            // if (password_needs_rehash($user["password"], PASSWORD_DEFAULT, ['cost' => PASSWORD_COST])) {
            //     $newHashedPassword = password_hash($plainPassword, PASSWORD_DEFAULT, ['cost' => PASSWORD_COST]);
            //     $updateStmt = $connect->prepare("UPDATE librarian SET password=? WHERE id=?");
            //     $updateStmt->bind_param("si", $newHashedPassword, $user["id"]);
            //     $updateStmt->execute();
            //     $updateStmt->close();
            // }

            header("Location: admin_index.php");
            exit();
        } else {
            // 密码错误
            logLoginAttempt($clientIP, false, $antiSpamConfig);
            $stmt->close();
            echo "<script>alert('用户名或密码错误！请重新登录！'); location.href='login.php';</script>";
            exit();
        }
    } else {
        // 用户不存在
        logLoginAttempt($clientIP, false, $antiSpamConfig);
        $stmt->close();
        echo "<script>alert('用户名或密码错误！请重新登录！'); location.href='login.php';</script>";
        exit();
    }

    $stmt->close();
}

// 退出登录逻辑
if (isset($_GET['tj']) && $_GET['tj'] == 'out') {
    session_destroy();
    header('location: login.php');
    exit;
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="shortcut icon" href="icon/favicon.ico" type="image/x-icon">
    <title>图书后台管理系统登录功能</title>
    <style>
        .bg-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            overflow: hidden;
            z-index: -1;
        }

        .bg-item {
            position: absolute;
            width: 100%;
            height: 100%;
            object-fit: cover;
            opacity: 0;
            transition: opacity 1s ease-in-out;
        }

        .bg-item.active {
            opacity: 1;
        }

        body * {
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            -webkit-user-drag: none;
            -moz-user-drag: none;
            -ms-user-drag: none;
            user-drag: none;
        }

        input, textarea {
            -webkit-user-select: auto !important;
            -moz-user-select: auto !important;
            -ms-user-select: auto !important;
            user-select: auto !important;
        }

        .copyright {
            position: fixed;
            bottom: 15px;
            left: 50%;
            transform: translateX(-50%);
            color: rgba(255,255,255,0.6);
            font-size: 14px;
            z-index: 100;
        }

        @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
        @keyframes slideInLeft { from { opacity: 0; transform: translateX(-50px); } to { opacity: 1; transform: translateX(0); } }
        @keyframes slideInRight { from { opacity: 0; transform: translateX(50px); } to { opacity: 1; transform: translateX(0); } }
        @keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }

        body { 
            margin: 0; 
            padding: 0; 
            font-family: 'Microsoft YaHei', sans-serif; 
            display: flex; 
            flex-direction: column; 
            justify-content: center; 
            align-items: center; 
            position: relative;
            min-height: 100vh; 
        }

        .big_box { 
            width: 960px; 
            height: 500px; 
            margin: auto; 
            background: rgba(255, 255, 255, 0.38); 
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); 
            overflow: hidden; 
            border-radius: 20px 0 0 20px; 
            backdrop-filter: blur(5px); 
            display: flex; 
            position: relative; 
            z-index: 10; 
        }

        .left_box { 
            width: 50%; 
            height: 100%; 
            overflow: hidden; 
            clip-path: ellipse(100% 100% at 0% 50%); 
        }
        .left_box img { 
            width: 100%; 
            height: 100%; 
            object-fit: cover; 
        }
        .right_box { 
            width: 50%; 
            text-align: center; 
            animation: slideInRight 0.8s ease-out; 
            display: flex; 
            flex-direction: column; 
            justify-content: center; 
            padding: 40px; 
            box-sizing: border-box; 
            background: transparent; 
        }
        table { 
            margin: auto; 
            animation: fadeIn 1s ease-out; 
            width: 100%; 
            max-width: 320px; 
        }
        h2 { 
            margin-top: 0; 
            color: #333; 
            animation: fadeIn 0.8s ease-out; 
            margin-bottom: 30px; 
        }
        .iput { 
            width: 100%; 
            height: 40px; 
            border: 1px solid #ddd; 
            border-radius: 6px; 
            padding: 0 15px; 
            font-size: 14px; 
            background-color: rgba(255, 255, 255, 0.9); 
        }
        .iput:focus { 
            border-color: #4a90e2; 
            box-shadow: 0 0 8px rgba(74, 144, 226, 0.2); 
            outline: none; 
        }
        .iput1, .iut2 { 
            width: 120px; 
            height: 45px; 
            font-size: 15px; 
            margin: 0 10px; 
            cursor: pointer; 
            transition: all 0.3s; 
        }
        .iput1 { 
            background-color: #4a90e2; 
            color: white; 
            border: none; 
            border-radius: 6px; 
        }
        .iput1:hover { 
            background-color: #3a7bc8; 
        }
        .iut2 { 
            background-color: #f5f5f5; 
            color: #333; 
            border: 1px solid #ddd; 
            border-radius: 6px; 
        }
        .iut2:hover { 
            background-color: #e0e0e0; 
        }
        .big_box.shake { 
            animation: shake 0.3s ease-in-out forwards; 
        }
        tr { 
            height: 60px; 
        }
        .verify-container { 
            position: relative; 
        }
        .verify-code { 
            position: absolute; 
            right: 5px; 
            top: 50%; 
            transform: translateY(-50%); 
            height: 30px; 
            cursor: pointer; 
            border-radius: 4px; 
        }

        .core-value {
            position: absolute;
            pointer-events: none;
            font-size: 18px;
            font-family: '微软雅黑';
            color: #FF0000;
            user-select: none;
            z-index: 999;
            transform: scale(0.1);
            transition: transform 0.3s ease-out;
        }

        .core-value.active {
            transform: scale(1);
        }
    </style>
</head>
<body oncontextmenu="return false;" ondragstart="return false;" onselectstart="return false;">
    <div class="bg-container" id="bgContainer">
        <img src="image/2.png" alt="背景1" class="bg-item">
        <img src="image/4.png" alt="背景2" class="bg-item active">
        <img src="image/5.png" alt="背景3" class="bg-item">
        <img src="image/1.jpg" alt="背景4" class="bg-item">
    </div>

    <div class="big_box">
        <div class="left_box"><img src="image/ysjf.jpg" draggable="false"></div>
        <div class="right_box">
            <h2>图书管理后台管理中心</h2>
            <form method="post" action="" onsubmit="return check()">
                <table>
                    <tr>
                        <td>
                            <input type="text" name="username" class="iput" placeholder="请输入用户名">
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <input type="password" name="pwd" class="iput" placeholder="请输入密码">
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div class="verify-container">
                                <input type="text" name="code" class="iput" placeholder="请输入验证码">
                                <img src="verify.php" alt="验证码" class="verify-code" onclick="this.src='verify.php?'+Math.random()" draggable="false">
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td align="center">
                            <input type="submit" name="login" value="登录" class="iput1">
                            <input type="button" name="register" value="注册" class="iut2" onclick="window.location.href='register.php'">
                        </td>
                    </tr>
                </table>
            </form>
        </div>
    </div>

    <div class="copyright">
        @2025-05.22 由唯出品/gitee/github/4230603094
    </div>

    <script>
        const bgImages = document.querySelectorAll('.bg-item');
        let currentIndex = 0;

        function switchBackground() {
            bgImages[currentIndex].classList.remove('active');
            currentIndex = (currentIndex + 1) % bgImages.length;
            bgImages[currentIndex].classList.add('active');
        }

        document.addEventListener('DOMContentLoaded', function() {
            setInterval(switchBackground, 5000);

            // 完全禁止右键菜单
            document.addEventListener('contextmenu', function(e) {
                e.preventDefault();
            });

            // 禁止选择文本
            document.addEventListener('selectstart', function(e) {
                e.preventDefault();
            });

            // 禁止拖拽
            document.addEventListener('dragstart', function(e) {
                e.preventDefault();
            });

            // 输入框聚焦效果
            const inputs = document.querySelectorAll('.iput');
            inputs.forEach(input => {
                input.addEventListener('focus', function() {
                    this.style.boxShadow = '0 0 8px rgba(74, 144, 226, 0.3)';
                });
                input.addEventListener('blur', function() {
                    this.style.boxShadow = '';
                });
            });

            // 确保所有图片不可拖拽
            document.querySelectorAll('img').forEach(img => {
                img.draggable = false;
            });
        });

        function check() {
            const username = document.querySelector('input[name="username"]').value;
            const password = document.querySelector('input[name="pwd"]').value;
            const code = document.querySelector('input[name="code"]').value;

            if (!username || !password || !code) {
                alert('用户名、密码和验证码不可为空！');
                return false;
            }

            return true;
        }

        
        const coreValues = [
            '富强', '民主', '文明', '和谐',
            '自由', '平等', '公正', '法治',
            '爱国', '敬业', '诚信', '友善'
        ].flatMap(word => [word, word]);

        document.addEventListener('click', (e) => {
            if (e.button !== 0) return;

            const x = e.clientX;
            const y = e.clientY;
            const randomIndex = Math.floor(Math.random() * coreValues.length);
            const valueText = coreValues[randomIndex];

            const span = document.createElement('span');
            span.className = 'core-value';
            span.textContent = valueText;
            span.style.left = `${x}px`;
            span.style.top = `${y}px`;

            span.classList.add('active');
            document.body.appendChild(span);

            setTimeout(() => {
                span.remove();
            }, 1000);
        });
    </script>
</body>
</html>